﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Kinect;
using System.Windows.Controls;
using System.Windows.Shapes;

namespace SkeletonRecorder.Kinect
{
    public class KinectSkeletonRecorder : Stream
    {
        public TimeSpan ReferanceTime { set; get; }

        FileStream _Stream;
        BinaryFormatter formatter = new BinaryFormatter();
        #region inherited from Stream
        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override void Flush()
        {
            _Stream.Flush();
        }

        public override long Length
        {
            get { return _Stream.Length; }
        }

        public override long Position
        {
            get
            {
                return _Stream.Position;
            }
            set
            {
                _Stream.Position = value; ;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _Stream.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _Stream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _Stream.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _Stream.Write(buffer,offset,count);
        }
        #endregion

        public void Create(String Filename)
        {
            _Stream = new FileStream(Filename, FileMode.OpenOrCreate);
            
        }

        public void Write(Skeleton[] skeleton, TimeSpan ts, int frame_number,Tuple<float,float,float,float> floor)
        {
            SkeletonRecord rec = new SkeletonRecord();
            rec.SkeletonCollection = skeleton;
            rec.TimeStamp = ReferanceTime - ts;
            rec.frameNumber = frame_number;
            rec.FloorPlane = floor;
            Write(rec);
        }

        public void Write(SkeletonRecord record)
        {
            formatter.Serialize(_Stream, record);
            Flush();
        }
        public void Read(out SkeletonRecord record)
        {
            record = (SkeletonRecord)formatter.Deserialize(_Stream);
        }

        public void Record(SkeletonFrame frame)
        {
            Skeleton[] s=new Skeleton[frame.SkeletonArrayLength];
            frame.CopySkeletonDataTo(s);
            Write(s, TimeSpan.FromMilliseconds(frame.Timestamp), frame.FrameNumber, frame.FloorClipPlane);
        }

        public void PlayFrame(Canvas c)
        {
            SkeletonRecord rec=null;
            Read(out rec);
            DrawSkeleton(c, rec); ;

        }


        // Draw the Skeleton Collections
        private void DrawSkeleton(Canvas c, SkeletonRecord rec)
        {
            for (int i = 0; i < rec.SkeletonCollection.Length; i++)
            {
                foreach (Joint j in rec.SkeletonCollection[i].Joints)
                {
                    Ellipse Joint = new Ellipse();

                   // c.SetValue("Top", j.Position.Y);
                    //c.SetValue("Top", j.Position.X);

                    c.Children.Add(Joint);
                    

                }
            }

        }


    
    }
    public class SkeletonRecord
    {
        public TimeSpan TimeStamp { set; get; } 
        public Skeleton[] SkeletonCollection{set;get;}
        public int frameNumber { get; set; }
        public Tuple<float, float, float, float> FloorPlane { get; set; }
    }
}
